package climspace.ejb;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import javax.persistence.EntityManager;
import climspace.data.WeatherData;
import climspace.data.WeatherStation;

public class FileParser {

	private EntityManager data;

	public void parseWeatherDataFile(String fileName) {
		try {
			FileInputStream fstream = new FileInputStream(fileName);

			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			for (int i = 0; i < 4; i++) {
				br.readLine();
			}
			int counter = 0;
			// Read File Line By Line
			while ((strLine = br.readLine()) != null) {

				if ("".equals(strLine)) {
					continue;
				}
				counter++;
				
				// System.out.println("*************counter: " + counter);
				WeatherData weatherData = parseWeatherDataLine(strLine);
				if (weatherData != null) {
					data.persist(weatherData);
				}
			}
			
			System.out.println("*************Processed (records): " + counter);

			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public WeatherData parseWeatherDataLine(String strLine){

		String valueDelim = "[ ]+"; // using regular expression '[ ]' delims
									// for <space>. '+' is for one or more
									// spaces.
		try {
			String values[] = strLine.split(valueDelim);
			WeatherData weatherData = setWeatherDataValues(values);
			return weatherData;
		} catch (Exception ex) {
			return null;
		}
	}
	
	public void parseWeatherStationFile(String fileName) {
		try {
			FileInputStream fstream;

			fstream = new FileInputStream(fileName);

			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;

			int counter = 1;

			// Read File Line By Line
			while ((strLine = br.readLine()) != null) {

				if ("".equals(strLine)) {
					continue;
				}

				if (strLine.endsWith(";")) {
					// String unParsedString[] = strLine.split(semiColonDelim);
					// String stringValue = unParsedString[0];
					// System.out.println("\nPrinting Line: " + strLine);
					// String values[] = stringValue.split(valueDelim, -1);
					if (counter == 1) {
						counter++;
					} else {

						WeatherStation weatherStation = parseWeatherStationLine(strLine);
						if(weatherStation!=null){
							data.persist(weatherStation);
						}
						
						counter++;
						// System.out.println("********************CoUNT: " + counter);
					}
				}
			}
			
			System.out.println("*************Processed (records): " + counter);

			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public WeatherStation parseWeatherStationLine(String strLine){

		String valueDelim = "[,]";  // using regular expression '[ ]' delims
									// for <space>. '+' is for one or more
									// spaces.
		
		try{
			String values[] = strLine.split(valueDelim);
		WeatherStation weatherStation = setWeatherStationValues(values);
		return weatherStation;
		} catch(Exception ex){
			return null;
		}
	}
	

	private WeatherStation setWeatherStationValues(String[] values) {
		WeatherStation weatherStation = new WeatherStation();
		weatherStation.setPrimary_id(values[0].trim());
		weatherStation.setSecondary_id(values[1].trim());
		weatherStation.setStation_name(values[2].trim());
		weatherStation.setState(values[3].trim());
		weatherStation.setCountry(values[4].trim());
		weatherStation.setLatitude(values[5].trim());
		weatherStation.setLongitude(values[6].trim());
		weatherStation.setElevation(values[7].trim());
		weatherStation.setMesowest_network_id(values[8].trim());
		weatherStation.setNetwork_name(values[9].trim());
		weatherStation.setStation_status(values[10].trim());
		weatherStation.setPrimary_provider_id(values[11].trim());
		weatherStation.setPrimary_provider(values[12].trim());
		weatherStation.setSecondary_provider_id(values[13].trim());
		weatherStation.setSecondary_provider(values[14].trim());
		weatherStation.setTertiary_provider(values[15].trim());
		weatherStation.setTertiary_provider_id(values[16].trim());
		return weatherStation;
	}

	public EntityManager getData() {
		return data;
	}

	public void setData(EntityManager data) {
		this.data = data;
	}

	private WeatherData setWeatherDataValues(String[] values) {
		// TODO: measurement of -9999.00 is probably NULL.
		
		WeatherData weatherData = new WeatherData();
		weatherData.setPrimary_id(values[1].trim());
		if (!"".equals(values[2].trim())) {
			SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd/HHmm");
			try {
				weatherData
						.setEntry_datetime(formatter.parse(values[2].trim()));
			} catch (ParseException e) {
				e.printStackTrace();
				System.out.println("Date is not in the expected format.");
			}
		}
		weatherData.setMnet_id(Double.parseDouble(values[3].trim()));
		weatherData.setStation_latitude(Double.parseDouble(values[4].trim()));
		weatherData.setStation_longitude(Double.parseDouble(values[5].trim()));
		weatherData.setStation_elevation(Double.parseDouble(values[6].trim()));
		weatherData.setTemperature(Double.parseDouble(values[7].trim()));
		weatherData.setWind_speed(Double.parseDouble(values[8].trim()));
		weatherData.setWind_direction(Double.parseDouble(values[9].trim()));
		weatherData.setWind_gust(Double.parseDouble(values[10].trim()));
		weatherData
				.setSea_level_pressure(Double.parseDouble(values[11].trim()));
		weatherData.setAltimeter(Double.parseDouble(values[12].trim()));
		weatherData.setDew_point(Double.parseDouble(values[13].trim()));
		weatherData.setRelative_humidity(Double.parseDouble(values[14].trim()));
		weatherData.setWeather_code(Double.parseDouble(values[15].trim()));
		weatherData.setPrecipitation(Double.parseDouble(values[16].trim()));
		return weatherData;
	}
}
